package com.hmkj.web.controller.trader;

import com.hmkj.common.entity.ResultEntity;
import com.hmkj.common.utils.BigDecimalUtil;
import com.hmkj.core.eolinker.endpoints.QuotationEndpoint;
import com.hmkj.core.eolinker.models.ModelRealTime;
import com.hmkj.core.model.index.OrderSimulationModel;
import com.hmkj.core.po.account.Account;
import com.hmkj.core.po.account.AccountSimulation;
import com.hmkj.core.po.marketing.UserEarningsRanking;
import com.hmkj.core.po.order.Order;
import com.hmkj.core.po.simulation.OrderSimulation;
import com.hmkj.core.po.simulation.Subscribe;
import com.hmkj.core.po.simulation.UserSubscribe;
import com.hmkj.core.po.user.User;
import com.hmkj.core.service.account.AccountService;
import com.hmkj.core.service.account.AccountSimulationService;
import com.hmkj.core.service.marketing.UserEarningsRankingService;
import com.hmkj.core.service.order.OrderService;
import com.hmkj.core.service.simulation.OrderSimulationService;
import com.hmkj.core.service.simulation.SubscribeService;
import com.hmkj.core.service.simulation.UserSubscribeService;
import com.hmkj.core.service.user.UserService;
import com.hmkj.web.controller.GenericController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * ......................我佛慈悲......................
 * ......................_oo0oo_.......................
 * .....................o8888888o......................
 * .....................88" . "88......................
 * .....................(| -_- |)......................
 * .....................0\  =  /0......................
 * ...................___/`---'\___....................
 * ..................' \\|     |// '...................
 * ................/ \\|||  :  |||// \.................
 * .............../ _||||| -卍-|||||- \................
 * ..............|   | \\\  -  /// |   |...............
 * ..............| \_|  ''\---/''  |_/ |...............
 * ..............\  .-\__  '-'  ___/-. /...............
 * ............___'. .'  /--.--\  `. .'___.............
 * .........."" '<  `.___\_<|>_/___.' >' ""............
 * ........| | :  `- \`.;`\ _ /`;.`/ - ` : | |.........
 * ........\  \ `_.   \_ __\ /__ _/   .-` /  /.........
 * ....=====`-.____`.___ \_____/___.-`___.-'=====......
 * ......................`=---='.......................
 * ....................................................
 * .................佛祖开光 ,永无BUG...................
 */
@Api(description = "统计接口相关")
@Slf4j
@RestController
@RequestMapping(GenericController.MEMBER_URL + "/count")
public class AppTraderController extends GenericController<Integer, User> {
    @Resource
    private UserService userService;
    @Resource
    private OrderSimulationService orderSimulationService;
    @Resource
    private UserEarningsRankingService userEarningsRankingService;
    @Resource
    private SubscribeService subscribeService;
    @Resource
    private UserSubscribeService userSubscribeService;
    @Resource
    private AccountService accountService;
    @Resource
    private OrderService orderService;
    @Resource
    private AccountSimulationService accountSimulationService;

    @ApiOperation(value = "用户盈利排行榜数据", notes = "用户盈利排行榜数据")
    @ResponseBody
    @RequestMapping(value = "/userEarningsRanking", method = RequestMethod.POST)
    public ResultEntity userEarningsRanking() throws Exception {
        User user = getLoginUser();
        long myUsersCount = userService.selectCount(new User(t -> {
            t.setInviteId(user.getId());
        }));
        List<UserEarningsRanking> rankings = userEarningsRankingService.findUserRankingData();
        return ok(m -> {
            m.put("ranks", rankings);
            m.put("inviteCode", user.getInviteCode());
            m.put("totalUser", myUsersCount);
        });
    }

    @ApiOperation(value = "首页最牛策略", notes = "首页最牛策略")
    @RequestMapping(value = "/goodStock", method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity goodStock() throws Exception {
        List<OrderSimulationModel> resultList = new ArrayList<>();
        User user = getLoginUser();
        List<OrderSimulation> list = orderSimulationService.select(new OrderSimulation(t -> {
            t.setStatus(OrderSimulation.STATUS.T7.code);
            t.setDelFlag(OrderSimulation.DELFLAG.NORMAL.code);
        }));
        if (CollectionUtils.isNotEmpty(list)) {
            int count = 0;//取前十条
            for (OrderSimulation os : list) {
                count++;
                if (count == 10) {
                    break;
                }
                //收益率 = 总盈亏/点买额度
                BigDecimal buy = os.getProfitCount();//总盈亏
                BigDecimal sell = os.getTradeCredit().multiply(BigDecimal.valueOf(10000));
                if (buy.compareTo(BigDecimal.ZERO) == 1 && sell.compareTo(BigDecimal.ZERO) == 1) {
                    BigDecimal earnRate = buy.divide(sell, 4, BigDecimal.ROUND_HALF_UP);
                    os.setRemark(earnRate.toString());
                } else {
                    os.setRemark("0");
                }
                OrderSimulationModel model = new OrderSimulationModel();
                model.setStockCode(os.getEquityCode());
                model.setStockName(os.getEquityName());
                model.setEarnRate(os.getRemark());
                model.setBuyDealPrice(os.getBuyDealPrice());
                model.setSellDealPrice(os.getSellDealPrice());
                model.setSellDealNumber(os.getSellDealNumber());
                model.setProfitCount(os.getProfitCount());
                model.setRemark(os.getRemark());
                User us = userService.selectByPrimaryKey(os.getUserId());
                model.setUserName(us.getUserName());
                model.setAvatar(us.getAvatarUrl());
                List<Subscribe> subscribes = subscribeService.select(new Subscribe(t -> {
                    t.setUserId(os.getUserId());
                    t.setDelFlag(Subscribe.DELFLAG.NORMAL.code);
                }));
                Subscribe sb = null;
                if (CollectionUtils.isNotEmpty(subscribes)) {
                    sb = subscribes.get(0);
                }
                if (null != sb) {
                    Subscribe finalSb = sb;
                    model.setSubId(sb.getId());
                    UserSubscribe userSubscribe = userSubscribeService.selectOne(new UserSubscribe(t -> {
                        t.setUserid(user.getId());
                        t.setIsSub(UserSubscribe.ISSUB.T2.code);
                        t.setSubscriberId(finalSb.getId());
                    }));
                    model.setIsSub(null == userSubscribe ? 0 : 1);
                } else {
                    model.setIsSub(0);
                }
                resultList.add(model);
            }
            Collections.sort(resultList, (o1, o2) -> o2.getRemark().compareTo(o1.getRemark()));
        }
        return ok(m -> {
            m.put("list", resultList);
        });
    }

    @ApiOperation(value = "我的策略", notes = "我的策略")
    @ResponseBody
    @RequestMapping(value = "strategy", method = RequestMethod.POST)
    public ResultEntity strategy() throws Exception {
        final Account account = accountService.selectByUID(getLoginUser().getId());
        Double floatProfit = holdingProfit(account.getUserId());
        return ok(m -> {
            m.put("total", account.getTotal());
            m.put("freeze", account.getFreeze());
            m.put("available", account.getAvailable());
            m.put("floatProfit", floatProfit);
        });
    }

    @ApiOperation(value = "炒股大赛", notes = "炒股大赛")
    @RequestMapping(value = "/stockMarket", method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity stockMarket() throws Exception {
        User user = getLoginUser();
        Map map = new HashMap<String, Object>();
        AccountSimulation accountSimulation = accountSimulationService.selectOne(new AccountSimulation(t -> {
            t.setUserId(user.getId());
        }));
        Double profit = holdingProfit(user.getId());
        map.put("total", accountSimulation.getTotal());
        map.put("freeze", accountSimulation.getFreeze());
        map.put("available", accountSimulation.getAvailable());
        map.put("profit", profit);
        return ok(map);
    }

    /**
     * 计算持仓盈亏
     *
     * @param
     * @return
     * @throws Exception
     */
    public double holdingProfit(Integer id) throws Exception {
        //计算持仓盈亏
        double total = 0;
        List<Order> orders = orderService.select(new Order(t -> {
            t.setUserId(id);
            t.setStatus(Order.STATUS.T3.code);
        }));
        if (CollectionUtils.isNotEmpty(orders)) {
            for (Order order : orders) {
                ModelRealTime realTime = QuotationEndpoint.realtime(order.getEquityCode());
                String lastPrice = realTime.getLast_price();
                BigDecimal buyDealPrice = order.getBuyDealPrice();
                BigDecimal dealNumber = BigDecimal.valueOf(order.getBuyDealNumber());
                //盈亏
                String profit = String.valueOf(BigDecimalUtil.mul(BigDecimalUtil.sub(Double.parseDouble(lastPrice), buyDealPrice.doubleValue()), dealNumber.doubleValue()));
                total = total + Double.parseDouble(profit);
            }
        }
        return total;
    }
}
